/*  linux/fs/msdos/namei.c
 *
 *  Written 1992,1993 by Werner Almesberger
 *  Hidden files 1995 by Albert Cahalan <albert@ccs.neu.edu> <adc@coe.neu.edu>
 *  Rewritten for constant inumbers 1999 by Al Viro
 *  Rewritten for Xen ARM 2010 by Mirrodance
 */

#include <fs/block.h>
#include <xen/cache.h>
#include <fs/fs.h>

#include <asm/init.h>

#include <fs/msdos_fs.h>

//static struct msdos_dir_entry *fat_dir_entries;
static struct dentry * msdos_dir_entries;
static struct super_block *msdos_super_blocks;
static struct fat32_bpb_info *fat32_bpb_infos;
static struct inode *msdos_inodes;

void init_dentry(struct fat32_bpb_info *);

extern struct super_block *
fat_read_super(struct super_block *sb, void *data, int silent,
		struct inode_operations *fs_dir_inode_ops);

static struct file_system_type fat_fs_type = {
	.name		= "msdos",
	.read_super	= fat_read_super,
};

void init_super_block()
{
	u8 *data;
	struct fat32_bpb_info *fat32_bpb_infos;

	data = (u8 *)xmalloc_bytes(512);
	mmc_read_block(1, 1, data);
	fat32_bpb_infos = (struct fat32_bpb_info *)(data + 11);
	
	//printk("(0xB):%u\n", fat32_bpb_infos->sector_bytes);
	//printk("(0xE):%u\n", fat32_bpb_infos->reserved_sectors);
	//printk("(0x10):%.2x\n", fat32_bpb_infos->fats);
	//printk("(0x24):%u\n", fat32_bpb_infos->fat_sectors);
	
	init_dentry(fat32_bpb_infos);
	msdos_super_blocks->s_root = msdos_dir_entries;
	msdos_super_blocks->s_type = &fat_fs_type;
}

void init_dentry(struct fat32_bpb_info *fat32_bpb_infos)
{
	unsigned short sector_bytes, reserved_sectors;
	unsigned long fat_sectors, dentry_begin;
	unsigned char fats;
	msdos_dir_entries = (struct dentry *)xmalloc_bytes(sizeof(struct dentry));
	msdos_inodes = (struct inode *)xmalloc_bytes(sizeof(struct inode));

	sector_bytes = fat32_bpb_infos->sector_bytes;
	reserved_sectors = fat32_bpb_infos->reserved_sectors;
	fat_sectors = fat32_bpb_infos->fat_sectors;
	fats = fat32_bpb_infos->fats;

	dentry_begin = fat_sectors*fats+reserved_sectors+1;
	memset(msdos_dir_entries, 0, sizeof(struct dentry));

	INIT_LIST_HEAD(&msdos_dir_entries->d_hash);
	INIT_LIST_HEAD(&msdos_dir_entries->d_lru);
	INIT_LIST_HEAD(&msdos_dir_entries->d_child);
	INIT_LIST_HEAD(&msdos_dir_entries->d_subdirs);
	INIT_LIST_HEAD(&msdos_dir_entries->d_alias);
	msdos_dir_entries->d_iname[0] = '/';
	//msdos_inodes->i_data.nrpages = ;
	
}

int __init init_fat_fs(void)
{
	return register_filesystem(&fat_fs_type);
}

void __exit exit_fat_fs(void)
{
	//unregister_filesystem(&fat_fs_type);
}
